<template>
  <div class="publish-page">
    <el-card>
      <div slot="header">
        <el-breadcrumb separator-class="el-icon-arrow-right">
          <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
          <el-breadcrumb-item>{{$route.query.id?'修改':'发布'}}文章</el-breadcrumb-item>
        </el-breadcrumb>
      </div>
      <!-- 表单 -->
      <el-form ref="articleForm" :model="articleForm" :rules="articleRules" label-width="120px">
        <el-form-item label="标题：" prop="title">
          <el-input style="width:400px" v-model="articleForm.title" placeholder="请输入文章标题"></el-input>
        </el-form-item>
        <el-form-item label="频道：" prop="channel_id">
          <my-channel v-model="articleForm.channel_id"></my-channel>
        </el-form-item>
        <el-form-item label="封面：" prop="cover">
          <el-radio-group @change="changeCoverType" v-model="articleForm.cover.type">
            <el-radio :label="1">单图</el-radio>
            <el-radio :label="3">三图</el-radio>
            <el-radio :label="0">无图</el-radio>
            <el-radio :label="-1">自动</el-radio>
          </el-radio-group>
          <!-- 当封面类型：1，3 的时候使用组件 -->
          <div v-if="articleForm.cover.type===1||articleForm.cover.type===3">
            <!-- action 上传图片接口地址 -->
            <!-- list-type 上传后文件的显示形态，卡片 -->
            <!-- name="image" 文件数据的字段名称 -->
            <!-- header 配置请求头，类型对象 -->
            <el-upload
              ref="upload"
              :action="$http.defaults.baseURL+'v1_0/upload'"
              name="image"
              :headers="{Authorization: `Bearer ${token}`}"
              :limit="articleForm.cover.type"
              :on-success="uploadSuccess"
              :on-remove="removeFile"
              :file-list="fileList"
              list-type="picture-card">
              <i class="el-icon-plus"></i>
            </el-upload>
          </div>
        </el-form-item>
        <el-form-item label="内容：" prop="content">
          <quillEditor @blur="checkContent" v-model="articleForm.content" :options="editorOption"></quillEditor>
        </el-form-item>
        <el-form-item label="" v-if="$route.query.id">
          <el-button @click="update(false)" type="success">修改文章</el-button>
          <el-button @click="update(true)">存入草稿</el-button>
        </el-form-item>
        <el-form-item label="" v-else>
          <el-button @click="submit(false)" type="primary">发布文章</el-button>
          <el-button @click="submit(true)">存入草稿</el-button>
        </el-form-item>
      </el-form>
    </el-card>
  </div>
</template>
<script>
import auth from '@/utils/auth'
import 'quill/dist/quill.core.css'
import 'quill/dist/quill.snow.css'
import 'quill/dist/quill.bubble.css'
import { quillEditor } from 'vue-quill-editor'
export default {
  name: 'PublishPage',
  components: {
    quillEditor
  },
  computed: {
    // el-upload 如果直接绑定js表达式，只要数据变化就导致组件刷新
    // 使用计算属性，其他数据有变化，当是这个计算属性没变化是有缓存的，不会导致组件刷新
    // 解决闪烁问题
    fileList () {
      return this.articleForm.cover.images.map(item => ({ url: item }))
    }
  },
  data () {
    const checkCover = (rule, value, cb) => {
      // value === this.articleForm.cover 封面对象
      // 1. 单图 type === 1  校验 images 中有一张图片
      // 2. 单图 type === 3  校验 images 中有三张图片
      // 其他情况正确
      if (value.type === 1) {
        if (!value.images[0]) {
          cb(new Error('请上传一张图片'))
        }
      }

      if (value.type === 3) {
        if (!(value.images[0] && value.images[1] && value.images[2])) {
          cb(new Error('请上传三张图片'))
        }
      }

      cb()
    }
    return {
      // 校验规则
      articleRules: {
        title: [
          { required: true, message: '请输入文章标题', trigger: 'blur' },
          { min: 4, max: 50, message: '文章标题4-50字符', trigger: 'blur' }
        ],
        channel_id: [
          { required: true, message: '请选择文章频道', trigger: 'change' }
        ],
        cover: [
          // 自定义校验
          { validator: checkCover, trigger: 'change' }
        ],
        content: [
          { required: true, message: '请输入文章内容', trigger: 'blur' }
        ]
      },
      // 表单对象
      articleForm: {
        // 标题
        title: null,
        // 频道ID
        channel_id: null,
        // 封面
        cover: {
          // 类型 1 单图 3 三图  0 无图  -1 自动 , 默认显示单图
          type: 1,
          // 图片数组
          images: []
        },
        // 内容
        content: null
      },
      // token数据
      token: auth.getToken(),
      // 富文本配置对象
      editorOption: {}
    }
  },
  created () {
    // 组件初始化：地址栏有ID代表修改，获取文章详情填充表单
    if (this.$route.query.id) {
      this.getArticle(this.$route.query.id)
    }
  },
  // 监听路由的参数变化：有ID是修改填充表单，没有呢就是发布清空表单
  beforeRouteUpdate (to, from, next) {
    // to 将要改变的路由信息对象
    if (to.query.id) {
      this.getArticle(to.query.id)
    } else {
      this.$refs.articleForm.resetFields()
    }
    next()
  },
  methods: {
    // 获取文章详情
    async getArticle (id) {
      const res = await this.$http.get('/v1_0/mp/articles/' + id)
      this.articleForm = res.data.data
    },
    // 修改文章
    update (draft) {
      this.$refs.articleForm.validate(async valid => {
        if (valid) {
          try {
            // 2. 发请求
            // get 获取  post 新增  delete 删除  put(完整修改) patch(局部修改) 修改
            // 满足以上规范的后台接口：resetfull 接口规范
            await this.$http.put(`/v1_0/mp/articles/${this.$route.query.id}?draft=${draft}`, this.articleForm)
            // 3. 成功
            this.$message.success('修改成功')
            this.$router.push('/article')
          } catch (e) {
            // 4. 失败
            this.$message.error('修改失败')
          }
        }
      })
    },
    // 提交文章
    submit (draft) {
      // 1. 校验
      this.$refs.articleForm.validate(async valid => {
        if (valid) {
          try {
            // 2. 发请求
            await this.$http.post('/v1_0/mp/articles?draft=' + draft, this.articleForm)
            // 3. 成功
            this.$message.success('发布成功')
            this.$router.push('/article')
          } catch (e) {
            // 4. 失败
            this.$message.error('发布失败')
          }
        }
      })
    },
    // 校验内容
    checkContent () {
      // 触发content校验
      this.$refs.articleForm.validateField('content')
    },
    // 切换封面类型
    changeCoverType () {
      // 重置数据
      this.articleForm.cover.images = []
      // 重置组件
      this.$refs.upload && this.$refs.upload.clearFiles()
      // 自己再次校验
      this.$refs.articleForm.validateField('cover')
    },
    // 上传图片成功
    uploadSuccess (res) {
      // res就是响应数据
      this.articleForm.cover.images.push(res.data.url)
      // 触发一次校验
      this.$refs.articleForm.validateField('cover')
    },
    // 删除文件
    removeFile (file) {
      console.log(file)
      // 主动：删除images数组中对应的图片
      // 1.发布的时候 file 中保存了之前上传图片响应的信息 response.data.url 图片地址
      // 2.编辑的时候 file-list 属性，导致file就是{url:'xxxxxxx'}
      // 根据这个图片地址找到images对应的索引，通过splice(索引,1) 删除图片
      const index = this.articleForm.cover.images.findIndex(item => item === file.url)
      this.articleForm.cover.images.splice(index, 1)
      // 自己再次校验
      this.$refs.articleForm.validateField('cover')
    }
  }
}
</script>
<style scoped lang="less">
.el-select {
  width: 400px;
}
// scoped 当前写的样式是无法作用到其他组件内部标签（组件根元素可以作用）
::v-deep .el-upload-list__item {
  transition: none;
}
::v-deep .ql-editor {
  height: 200px;
}
</style>
